#include <stdio.h>
#include <string.h>
#include <mpi.h>

#include "disp.h"
#include "bm.h"
#include "naive.h"
#include "rand.h"

int main (int argc, char * argv[]) {
	
	// MPI Initialization
	MPI_Init(&argc, &argv);
	
	
	// example: mpiexec -n 4 search 100000000 100000 abcd
	if (argc < 4)
	{
		int rank;
		
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		
		if (rank == 0) printf("mpiexec -n <number_of_processor> search <buffer_size> <chunk_size> <pattern_string>\n");
		return 0;
	}
	
	char	*textBuffer;
	int		textSize;
	int		chunkSize;
	int		*results;
	char	*pattern = argv[3];
	double	timeTotal;

	
	textSize	= atoi(argv[1]);
	chunkSize	= atoi(argv[2]);
	
	
	// String Dispatcher Initiaization
	Disp_Init(&textBuffer, textSize, chunkSize, strlen(pattern)-1);

	if (Disp_Get_Rank() == ROOT)
	{	
		randStr(textBuffer, textSize, pattern, textSize / 10 + 1);	// Randomizing textBuffer for testing purpose
		timeTotal = MPI_Wtime();
	}
	
	Disp_Sync_String(pattern, strlen(pattern));						// Broadcasting pattern string among all processing units
	
	BM_Init(pattern, strlen(pattern));								// Initializing Boyer-Moore, i.e. generating jump tables
	
	
	Disp_Iterator_Type iterator;
	for (iterator = Disp_Get_Begin_Iterator(); 
		 iterator != Disp_Get_End_Iterator(iterator); 
		 iterator = Disp_Get_Next_Iterator(iterator))
	{
		BM_Search(Disp_Get_Chunk(iterator), Disp_Get_Chunk_Size());
	}
	
	Disp_Gather(&results);
	
	if (Disp_Get_Rank() == ROOT) timeTotal = MPI_Wtime() - timeTotal;

	Disp_Print_Results(results);

	// String Dispatcher Finilization
	Disp_Finalize();
	
	if (Disp_Get_Rank() == ROOT) printf("TotalTime :\t %f\n", timeTotal);
	
	return MPI_Finalize();

}
